home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include "csemq.hpp"
-
-
- /* Constructor */
- Csemq::Csemq()
- {
- sem = 0L;
- priority = CSC_NO_THREAD;
- }
-
-
- /* Another Constructor */
- Csemq::Csemq(long lValue)
- {
- sem = lValue;
- priority = CSC_NO_THREAD;
- }
-
-
- /* Used to return a thread for execution based on a
- round-robin-like scheduling algorithm */
- int Csemq::Dequeue()
- {
- int nTask = CSC_NO_THREAD;
- long task;
-
- long tmp;
- int i;
-
- if (sem < 0)
- {
- //this implements a somewhat round-robin scheduling algorithm
- task = _lrotl(1, priority + 1);
- tmp = sem & ~CSC_IDLE;
-
- /* scan the semaphore queue structure bit-by-bit */
- for (i = 0; i < CSC_NO_THREAD + 1; i++)
- {
- if (task & tmp)
- break;
- else
- task = _lrotl(task, 1);
- }
-
- sem &= ~task;
- if (sem == CSC_IDLE)
- sem = 0;
-
- if (i <= CSC_NO_THREAD)
- nTask = long (i + priority + 1) % 32L;
-
- }
-
- priority = nTask;
-
- return (nTask);
- }
-
-
- /* Used to put a thread in the semaphore queue */
- void Csemq::Enqueue(int nThread)
- {
- if ((nThread <= CSC_NO_THREAD) || (sem <= 0))
- {
- sem |= (1L << nThread) | CSC_IDLE ;
- }
- }
-
-
- /* Used to update the semaphore count by the specified
- amount */
- void Csemq::UpdateCount(long lValue)
- {
- long lTmp;
-
- if (sem >= 0)
- {
- lTmp = sem + lValue;
- if (lTmp >= 0)
- sem = lTmp;
- }
- }
-
-
- /* Used to return an indicator to the caller telling
- it if the semaphore structure is a counter or a queue */
- csemq_type Csemq::GetType()
- {
- csemq_type nType = CST_COUNT;
-
- if (sem < 0)
- nType = CST_QUEUE;
-
- return (nType);
- }
-
-
- /* Used to get the count of a semaphore */
- long Csemq::GetCount()
- {
- return (sem);
- }
-